﻿using System;
using System.Collections.Generic;

namespace KryptecizerBase
{
    /// <summary>
    /// Krypto Text
    /// </summary>
    public class KryptoText : List<Char>
    {
        #region public methods
        /// <summary>
        /// Fills the specified text in instance.
        /// Calls OnChanged event.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>success</returns>
        public bool Fill(string text)
        {
            bool result = false;
            this.Clear();
            if (text == null)
                return result;
            else
                foreach (System.Char item in text)
                    this.Add(item);
            result = true;

            OnChanged();
            return result;
        }

        /// <summary>
        /// Gets the text as string.
        /// </summary>
        /// <returns>the text</returns>
        public string GetAsString()
        {
            string result = String.Empty;
            foreach (Char item in this)
                result += item;
            return result;
        }

        /// <summary>
        /// Static method.
        /// Shifts the specified base char.
        /// ASCII-signs in the range of [97, 122] will be substitutid with lowercase signs.
        /// (Decreased by 32.)
        /// Non-letter signs will be returned without any changes.
        /// </summary>
        /// <param name="baseChar">The base char.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>new Char</returns>
        public static Char Shift(char baseChar, int offset)
        {
            int asciiIndex = (int)baseChar;
            if ((asciiIndex <= 122) && (asciiIndex >= 97))
                asciiIndex -= 32;
            if ((asciiIndex >= 65) && (asciiIndex <= 90))
            {
                asciiIndex += offset;
                if (asciiIndex > 90)
                    asciiIndex -= 26;
                if (asciiIndex < 65)
                    asciiIndex += 26;
            }
            return Convert.ToChar(asciiIndex);
        }

        /// <summary>
        /// Static method.
        /// Eleminates all special signs.
        /// ASCII-signs in the range of [97; 122] and elements with the values of 228, 246 or 252
        /// will be substitutid with lowercase signs.
        /// Elements with the values of 196, 214 or 220 will be substitutid 
        /// with their "double-letter"-equivalent.
        /// Other signs will be deleted.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static string EleminateSpecialSigns(string text)
        {
            string tmpText = text.Replace(Environment.NewLine, " ");
            string result = String.Empty;
            char newchar;
            foreach (Char item in tmpText)
            {
                newchar = item;
                if ((((int)newchar >= 97) && ((int)newchar <= 122))
                    || ((int)newchar == 228) || ((int)newchar == 246)
                    ||((int)newchar == 252))
                    newchar = Convert.ToChar((int)newchar - 32);
                if ((int)newchar == 196)
                    result += "AE";
                else if ((int)newchar == 214)
                    result += "OE";
                else if ((int)newchar == 220)
                    result += "UE";
                else if (((int)newchar >= 65) && ((int)newchar <= 90))
                    result += newchar;
            }
            return result;
        }

        /// <summary>
        /// Gets the string in groups of five. Seperated by a space. 
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>Grouped string</returns>
        public static string GetGroupedString(string text)
        {
            string result = String.Empty;
            for (int i = 0; i < text.Length; i++)
            {
                result += text[i];
                if (((i+1) % 5) == 0)
                    result += " ";
            }
            return result;
        }

        /// <summary>
        /// Shifts the char specified by index.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>new char</returns>
        public Char Shift(int index, int offset)
        {
            return Shift(this[index], offset);
        }

        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns>new KryptoText</returns>
        public KryptoText Clone()
        {
            KryptoText result = new KryptoText();
            result.Fill(this.GetAsString());
            return result;
        }
        #endregion

        /// <summary>
        /// Called when [changed].
        /// </summary>
        private void OnChanged()
        {
            if (Changed != null)
                Changed();
        }

        /// <summary>
        /// Handles the Changed event.
        /// </summary>
        public delegate void ChangedEventHandler();
        /// <summary>
        /// Occurs when [changed].
        /// </summary>
        public event ChangedEventHandler Changed;
    }
}
